package com.yoogor.xposedtest;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.ws.WebSocket;
import okhttp3.ws.WebSocketCall;
import okhttp3.ws.WebSocketListener;
import okio.Buffer;

/**
 * Created by paron on 2018/3/24.
 */

public class WebsocketConn {
    private static final String LOGTAG = "websocket";
    private static WebSocket _webSocket = null;

//    private static Handler handler = null;

    private WebsocketConn() {
        conn();
    }

    private static class Instance {
        static WebsocketConn instance = new WebsocketConn();
    }

    public static WebsocketConn instance() {
        return Instance.instance;
    }

    private static void conn() {
        String url = AppConfig.getWebsocketUrl();
        if (_webSocket != null) {
            try {
                _webSocket.close(-1, "reason");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        final OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(30, TimeUnit.MINUTES)
                .writeTimeout(30, TimeUnit.MINUTES)
                .connectTimeout(30, TimeUnit.MINUTES)
                .build();
        final Request request = new Request.Builder()
                .url(url)
                .build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                WebSocketCall webSocketCall = WebSocketCall.create(okHttpClient, request);
                webSocketCall.enqueue(new WebSocketListener() {
                    @Override
                    public void onOpen(WebSocket webSocket, Response response) {
                        //保存引用，用于后续操作
                        _webSocket = webSocket;
                        //打印一些内容
                        System.out.println("client onOpen");
                        System.out.println("client request header:" + response.request().headers());
                        System.out.println("client response header:" + response.headers());
                        System.out.println("client response:" + response);
                    }

                    @Override
                    public void onFailure(IOException e, Response response) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onMessage(ResponseBody message) throws IOException {
                        String content = message.string();
                        Log.e(LOGTAG, content);
                        if (runnable != null) {
                            try {
                                JSONObject jsonObject = new JSONObject(content);
                                if (TextUtils.equals("cmd", jsonObject.optString("type"))) {
                                    runnable.onMessage(jsonObject);
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                    @Override
                    public void onPong(Buffer payload) {

                    }

                    @Override
                    public void onClose(int code, String reason) {
                    }
                });
            }
        }).start();
    }

    private static void retryDelay() {
        try {
            _webSocket.close(0, "ping failed");
        } catch (Exception e) {
            e.printStackTrace();
        }
        conn();
    }

    public static void sendMessage(final String message) {
        HandleThread.instance().getHandler().post(new Runnable() {
            @Override
            public void run() {
                try {
                    _webSocket.sendMessage(RequestBody.create(WebSocket.TEXT, message));
                } catch (IOException e) {
                    e.printStackTrace();
                    conn();
                }
            }
        });
    }

    private static MessageListerner runnable;

    public static void setOnReloadListener(MessageListerner reloadListener) {
        runnable = reloadListener;
    }

    public interface MessageListerner {
        void onMessage(JSONObject jsonObject);
    }
}
